<?php
/**
 * @file Wiki.php
 *
 * A parser for Wiki-Markup.
 *
 * This class can parse from Wiki-Markup to HTML and the other way around.
 *
 * http://code.google.com/p/rpd/wiki/Wiki.php
 *
 * New BSD License
 * \n
 * Copyright (c) 2010 Rpd-Team
 *
 * @namespace  rpd
 * @since      0.0.1
 * @version    0.0.1
 */

/**
 *
 */

define("RPD_WIKI_AUTO", 1);
define("RPD_WIKI_HTML", 2);
define("RPD_WIKI_TEXT", 4);

class Wiki {

	private $_content = "";

	function __construct($content = "", $mode = RPD_WIKI_AUTO) {
		if ($mode == RPD_WIKI_HTML || strip_tags($content, '<br />') != $content)
		{
			$mode = RPD_WIKI_HTML;

			$content = str_replace('<br />', "\r\n", $content);
		}
		else
		{
			$mode = RPD_WIKI_TEXT;
			$content = htmlspecialchars($content);

			$content = nl2br($content, true);
			$content = str_replace("\r", "", $content);
			$content = str_replace("\n", "", $content);
		}

		$this->_content = $content;

	}
	
	public static function parseNewLine($wiki_string)
	{
		$transform = array(
			"\r\n" => "<br />"
		);
		
		return strtr($wiki_string, $transform);
	}
	
	public static function parseLink($wiki_text)
	{
		$a = array();
		
		$site_pattern = '#\[\[([^\s]*)\s{0,1}([^\]\]]*)\]\]#';
		preg_match_all($site_pattern, $wiki_text, $a, PREG_SET_ORDER);
		
		$link_transform = array();
		foreach ($a as $set)
		{
			$link_transform[$set[0]] = '<a href="'. $set[1] .'">'
			                         . (($set[2] == "")? $set[1]: $set[2]) . '</a>';
		}
		
		$parseLink = strtr($wiki_text, $link_transform);
		
		/*
		 * Tranform raw url
		 */
		$url_pattern = '#(^|[^\"=]{1})(http://|ftp://|mailto:|news:)([^\s<>]+)([\s\n<>]|$)#sm';
		return preg_replace($url_pattern,
		                       "\\1<a href=\"\\2\\3\">\\2\\3</a>\\4",
		                       $parseLink);
	}
	
	public static function parseParagraph($wiki_string)
	{
		$transform = array(
			"\r\n\r\n" => "</p><p>",
			"\n\n"     => "</p><p>",
		);
		
		
		return strtr($wiki_string, $transform);
	}
	
	public static function parseList($wiki_string)
	{
		// Replacing lists
		$parseList = preg_replace("#(?<begin>\\*{1}[ ]{1})(?<content>.+)(?<end>[^*])#m",
		                          '<li>\\2</li>',
		                          $wiki_string);
		
		
		return preg_replace("#(?<content>\\<li\\>{1}.+\\<\\/li\\>)#m",
		                    "<ul>\\1</ul>",
		                     $parseList);
	}
	
	public static function toHTML($wiki_string, $wrapper = "<p>")
	{
		$toHTML = $wiki_string;
		
		$toHTML = Wiki::parseList($toHTML);
		                       
		$toHTML = Wiki::parseParagraph($toHTML);		
		
		$toHTML = Wiki::parseNewLine($toHTML);
		
		/*
		 * Transform inner links
		 */
		$toHTML = Wiki::parseLink($toHTML);
		
		/*
		 * Switch state of wrapper tags (open <-> close)
		 */
		$wrapper_undo = array(
			"</" => "<",
			"<"  => "</"
		);
		
		if ($wrapper != "")
		{
			$toHTML .= strtr($wrapper, $wrapper_undo);
		}
		
		return $toHTML;
	}

	function __toString()
	{
		return $this->_content;
	}
}

?>